<template>
  <div class="file-upload-container">
    <el-upload
      ref="uploadRef"
      class="upload-dragger"
      :action="uploadUrl"
      :headers="uploadHeaders"
      :data="extraData"
      :before-upload="beforeUpload"
      :on-success="handleSuccess"
      :on-error="handleError"
      :on-progress="handleProgress"
      :on-remove="handleRemove"
      :on-change="handleChange"
      :file-list="fileList"
      :limit="limit"
      :multiple="multiple"
      :disabled="disabled"
      :auto-upload="autoUpload"
      drag
    >
      <div class="upload-content">
        <div class="upload-icon">
          <el-icon size="60" :color="disabled ? '#C0C4CC' : '#409EFF'">
            <UploadFilled />
          </el-icon>
        </div>
        
        <div class="upload-text">
          <p class="upload-title">
            {{ uploadText || '点击或拖拽文件到此区域上传' }}
          </p>
          <p class="upload-hint">
            {{ hintText || `支持 ${acceptTypes.join('、')} 格式，文件大小不超过 ${formatFileSize(maxSize)}` }}
          </p>
        </div>
        
        <!-- 上传进度 -->
        <div v-if="uploading" class="upload-progress">
          <el-progress
            :percentage="uploadProgress"
            :status="uploadStatus"
            :stroke-width="6"
          />
          <p class="progress-text">
            {{ uploadStatus === 'success' ? '上传完成' : `上传中... ${uploadProgress}%` }}
          </p>
        </div>
      </div>
    </el-upload>

    <!-- 文件列表 -->
    <div v-if="showFileList && fileList.length > 0" class="file-list">
      <div class="file-list-title">
        <span>已上传文件</span>
        <el-button v-if="allowClear" type="text" size="small" @click="clearFiles">
          <el-icon><Delete /></el-icon>
          清空
        </el-button>
      </div>
      
      <div class="file-items">
        <div
          v-for="(file, index) in fileList"
          :key="file.uid || index"
          class="file-item"
        >
          <div class="file-info">
            <el-icon class="file-icon" :color="getFileStatusColor(file.status)">
              <Document />
            </el-icon>
            <div class="file-details">
              <span class="file-name" :title="file.name">{{ file.name }}</span>
              <span class="file-size">{{ formatFileSize(file.size) }}</span>
            </div>
          </div>
          
          <div class="file-actions">
            <el-button
              v-if="file.status === 'success' && allowPreview"
              type="text"
              size="small"
              @click="previewFile(file)"
            >
              <el-icon><View /></el-icon>
            </el-button>
            <el-button
              v-if="file.status === 'success' && allowDownload"
              type="text"
              size="small"
              @click="downloadFile(file)"
            >
              <el-icon><Download /></el-icon>
            </el-button>
            <el-button
              v-if="!disabled"
              type="text"
              size="small"
              @click="removeFile(file)"
            >
              <el-icon><Delete /></el-icon>
            </el-button>
          </div>
          
          <!-- 文件上传进度 -->
          <div v-if="file.status === 'uploading'" class="file-progress">
            <el-progress
              :percentage="file.percentage || 0"
              :stroke-width="4"
              :show-text="false"
            />
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, watch } from 'vue'
import { 
  UploadFilled, 
  Document, 
  View, 
  Download, 
  Delete 
} from '@element-plus/icons-vue'
import { ElMessage } from 'element-plus'
import { validateFile, formatFileSize } from '@/utils'
import { FILE_UPLOAD_CONFIG } from '@/utils/constants'

const props = defineProps({
  // 上传地址
  uploadUrl: {
    type: String,
    default: '/api/student/paper/upload'
  },
  // 上传请求头
  headers: {
    type: Object,
    default: () => ({})
  },
  // 额外的表单数据
  data: {
    type: Object,
    default: () => ({})
  },
  // 文件列表
  modelValue: {
    type: Array,
    default: () => []
  },
  // 允许的文件类型
  accept: {
    type: Array,
    default: () => FILE_UPLOAD_CONFIG.ALLOWED_EXTENSIONS
  },
  // 文件大小限制（字节）
  maxSize: {
    type: Number,
    default: 30 * 1024 * 1024 // 30MB
  },
  // 上传数量限制
  limit: {
    type: Number,
    default: 1
  },
  // 是否支持多选
  multiple: {
    type: Boolean,
    default: false
  },
  // 是否禁用
  disabled: {
    type: Boolean,
    default: false
  },
  // 是否自动上传
  autoUpload: {
    type: Boolean,
    default: true
  },
  // 上传提示文字
  uploadText: {
    type: String,
    default: ''
  },
  // 提示文字
  hintText: {
    type: String,
    default: ''
  },
  // 是否显示文件列表
  showFileList: {
    type: Boolean,
    default: true
  },
  // 是否允许清空
  allowClear: {
    type: Boolean,
    default: true
  },
  // 是否允许预览
  allowPreview: {
    type: Boolean,
    default: false
  },
  // 是否允许下载
  allowDownload: {
    type: Boolean,
    default: false
  }
})

const emit = defineEmits([
  'update:modelValue',
  'success',
  'error',
  'progress',
  'preview',
  'download'
])

// 组件引用
const uploadRef = ref()

// 上传状态
const uploading = ref(false)
const uploadProgress = ref(0)
const uploadStatus = ref('')

// 文件列表
const fileList = ref([...props.modelValue])

// 计算属性
const uploadHeaders = computed(() => {
  const token = localStorage.getItem('graduation_check_token')
  return {
    'Authorization': token ? `Bearer ${token}` : '',
    ...props.headers
  }
})

const extraData = computed(() => props.data)

const acceptTypes = computed(() => {
  return props.accept.map(type => type.replace('.', '').toUpperCase())
})

// 监听外部文件列表变化
watch(() => props.modelValue, (newValue) => {
  fileList.value = [...newValue]
}, { deep: true })

// 监听内部文件列表变化
watch(fileList, (newValue) => {
  emit('update:modelValue', newValue)
}, { deep: true })

// 文件变化处理（文件选择时触发）
const handleChange = (file, fileListParam) => {
  if (!props.autoUpload && file.status === 'ready') {
    // 验证文件
    const validation = validateFile(file.raw, {
      maxSize: props.maxSize,
      allowedTypes: props.accept
    })
    
    if (!validation.valid) {
      ElMessage.error(validation.message)
      // 移除无效文件
      const uploadInstance = uploadRef.value
      if (uploadInstance) {
        uploadInstance.handleRemove(file)
      }
      return
    }
    
    // 手动添加到文件列表
    const fileItem = {
      uid: file.uid,
      name: file.name,
      size: file.size,
      status: 'ready',
      raw: file.raw,
      originFileObj: file.raw
    }
    
    fileList.value = [fileItem]
    ElMessage.success('文件选择成功，点击上传按钮开始上传')
  }
}

// 上传前验证
const beforeUpload = (file) => {
  // 如果不是自动上传，阻止上传
  if (!props.autoUpload) {
    return false
  }
  
  const validation = validateFile(file, {
    maxSize: props.maxSize,
    allowedTypes: props.accept
  })
  
  if (!validation.valid) {
    ElMessage.error(validation.message)
    return false
  }
  
  // 检查文件数量限制
  if (fileList.value.length >= props.limit) {
    ElMessage.error(`最多只能上传 ${props.limit} 个文件`)
    return false
  }
  
  uploading.value = true
  uploadProgress.value = 0
  uploadStatus.value = ''
  
  return true
}

// 上传成功
const handleSuccess = (response, file) => {
  uploading.value = false
  uploadProgress.value = 100
  uploadStatus.value = 'success'
  
  // 更新文件信息
  const fileItem = {
    uid: file.uid,
    name: file.name,
    size: file.size,
    status: 'success',
    response: response,
    url: response.downloadUrl
  }
  
  // 添加到文件列表
  const index = fileList.value.findIndex(item => item.uid === file.uid)
  if (index > -1) {
    fileList.value[index] = fileItem
  } else {
    fileList.value.push(fileItem)
  }
  
  ElMessage.success('文件上传成功')
  emit('success', response, fileItem)
}

// 上传失败
const handleError = (error, file) => {
  uploading.value = false
  uploadStatus.value = 'exception'
  
  console.error('文件上传失败:', error)
  ElMessage.error('文件上传失败，请重试')
  emit('error', error, file)
}

// 上传进度
const handleProgress = (event, file) => {
  uploadProgress.value = Math.round(event.percent)
  emit('progress', event, file)
}

// 移除文件
const handleRemove = (file) => {
  const index = fileList.value.findIndex(item => item.uid === file.uid)
  if (index > -1) {
    fileList.value.splice(index, 1)
  }
}

// 移除文件
const removeFile = (file) => {
  if (uploadRef.value) {
    uploadRef.value.handleRemove(file)
  }
}

// 清空文件
const clearFiles = () => {
  fileList.value = []
  if (uploadRef.value) {
    uploadRef.value.clearFiles()
  }
}

// 预览文件
const previewFile = (file) => {
  emit('preview', file)
}

// 下载文件
const downloadFile = (file) => {
  emit('download', file)
}

// 获取文件状态颜色
const getFileStatusColor = (status) => {
  switch (status) {
    case 'success':
      return '#67C23A'
    case 'uploading':
      return '#409EFF'
    case 'fail':
      return '#F56C6C'
    default:
      return '#909399'
  }
}

// 暴露方法
defineExpose({
  clearFiles,
  submit: () => uploadRef.value?.submit()
})
</script>

<style scoped>
.file-upload-container {
  width: 100%;
}

/* 上传区域 */
.upload-dragger {
  width: 100%;
}

.upload-dragger :deep(.el-upload-dragger) {
  padding: 2rem;
  border-radius: 12px;
  border: 2px dashed #dcdfe6;
  background-color: #fafcff;
  transition: all 0.3s ease;
}

.upload-dragger :deep(.el-upload-dragger:hover) {
  border-color: #409EFF;
  background-color: #f0f9ff;
}

.upload-dragger :deep(.el-upload-dragger.is-dragover) {
  border-color: #409EFF;
  background-color: #e3f2fd;
}

.upload-content {
  text-align: center;
}

.upload-icon {
  margin-bottom: 1rem;
}

.upload-title {
  font-size: 1.1rem;
  font-weight: 500;
  color: #303133;
  margin: 0 0 0.5rem 0;
}

.upload-hint {
  font-size: 0.9rem;
  color: #909399;
  margin: 0;
}

/* 上传进度 */
.upload-progress {
  margin-top: 1.5rem;
  padding: 0 2rem;
}

.progress-text {
  margin-top: 0.5rem;
  font-size: 0.9rem;
  color: #606266;
}

/* 文件列表 */
.file-list {
  margin-top: 1.5rem;
  border: 1px solid #ebeef5;
  border-radius: 8px;
  background-color: #fff;
}

.file-list-title {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 1rem 1.5rem;
  border-bottom: 1px solid #ebeef5;
  background-color: #fafbfc;
  font-weight: 500;
  color: #303133;
}

.file-items {
  padding: 0.5rem 0;
}

/* 文件项 */
.file-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0.8rem 1.5rem;
  border-bottom: 1px solid #f5f7fa;
  position: relative;
}

.file-item:last-child {
  border-bottom: none;
}

.file-info {
  display: flex;
  align-items: center;
  flex: 1;
  min-width: 0;
}

.file-icon {
  margin-right: 0.8rem;
  flex-shrink: 0;
}

.file-details {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.file-name {
  font-weight: 500;
  color: #303133;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 200px;
}

.file-size {
  font-size: 0.8rem;
  color: #909399;
  margin-top: 0.2rem;
}

.file-actions {
  display: flex;
  gap: 0.5rem;
  flex-shrink: 0;
}

.file-progress {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .upload-dragger :deep(.el-upload-dragger) {
    padding: 1.5rem;
  }
  
  .upload-icon {
    margin-bottom: 0.8rem;
  }
  
  .upload-title {
    font-size: 1rem;
  }
  
  .upload-hint {
    font-size: 0.8rem;
  }
  
  .file-item {
    padding: 0.6rem 1rem;
  }
  
  .file-name {
    max-width: 150px;
  }
}
</style>